import os
import csv
import random
import string
from collections import namedtuple
from .phen2gene import results
PHEN2GENE = namedtuple('PHEN2GENE', ['rank', 'symbol', 'entrez_id', 'score', 'status'])


def id_generator(size=32, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))


def create_gene_list(gene_symbols: list[str]):
    if gene_symbols:
        gene_list_file = f'/tmp/phen2gene_{id_generator()}.gene_list'
        with open(gene_list_file, 'w') as fo:
            for gene_symbol in gene_symbols:
                fo.write(f'{gene_symbol}\n')
        return gene_list_file
    return None


def run_phen2gene(knowledge_base_path: str, hpos: list[str], gene_symbols: list[str],  weight_model='sk') -> list[PHEN2GENE]:
    gene_list_file = create_gene_list(gene_symbols=gene_symbols)
    out_prefix = f'phen2gene_{id_generator()}'
    results(
        KBpath=knowledge_base_path,
        files=None,
        manuals=hpos,
        user_defineds=None,
        weight_model=weight_model,
        weight_only=None,
        output_path='/tmp',
        output_file_name=out_prefix,
        json_formatting=False,
        gene_weight=None,
        cutoff=None,
        genelist=gene_list_file,
        verbosity=False,
        cl=True
    )
    outfile = f'/tmp/{out_prefix}.associated_gene_list'
    phen2genes = list()
    with open(outfile) as fi:
        reader = csv.DictReader(fi, delimiter='\t')
        for row in reader:
            phen2genes.append(PHEN2GENE(
                rank=int(row.get('Rank')),
                entrez_id=row.get('ID'),
                symbol=row.get('Gene'),
                score=float(row.get('Score')),
                status=row.get('Status')
            ))
    if gene_list_file and os.path.exists(gene_list_file):
        os.remove(gene_list_file)
    if outfile and os.path.exists(outfile):
        os.remove(outfile)
    if os.path.exists('./tmp/') and len(os.listdir('./tmp/')) == 0:
        os.removedirs('./tmp/')
    return phen2genes
